#include "Buffer.h"
#include "Util.h"

namespace mylog
{
    Buffer::Buffer()
        : g_conf_data(mylog::Util::JsonData::GetJsonData())
        , write_pos_(0)
        , read_pos_(0)
        , buffer_(g_conf_data->buffer_size, 0)
    {
    }

    void Buffer::push(const char* data, size_t len)
    {
        // 确保容量足够，在容量不足时会扩容
        toBeEnouth(len);
        std::copy(data, data + len, &buffer_[write_pos_]);
        write_pos_ += len;
    }

    char* Buffer::readBegin(size_t len)
    {
        assert(len <= readableSize());
        return &buffer_[read_pos_];
    }

    bool Buffer::isEmpty() const
    {
        return read_pos_ == write_pos_;
    }

    void Buffer::swap(Buffer& buf)
    {
        buffer_.swap(buf.buffer_);
        std::swap(write_pos_, buf.write_pos_);
        std::swap(read_pos_, buf.read_pos_);
    }

    size_t Buffer::writableSize() const 
    {
        // 写空间剩余容量
        return buffer_.capacity() - write_pos_;
    }

    size_t Buffer::readableSize() const
    {
        return write_pos_ - read_pos_;
    }

    const char* Buffer::begin() const
    {
        return &buffer_[read_pos_];
    }

    void Buffer::moveWritePos(size_t len)
    {
        assert(len <= writableSize());
        write_pos_ += len;
    }

    void Buffer::moveReadPos(size_t len)
    {
        assert(len <= readableSize());
        read_pos_ += len;
    }

    void Buffer::reset()
    {
        write_pos_ = 0;
        read_pos_ = 0;
    }

    void Buffer::toBeEnouth(size_t len)
    {
        int buffersize = buffer_.capacity();
        if (len >= writableSize())
        {
            if (buffersize < g_conf_data->threshold)
            {
                buffer_.resize(2 * buffersize);
            }
            else
            {
                buffer_.resize(g_conf_data->linear_growth + buffersize);
            }
        }
    }
} // namespace log